package com.v1.video.view;

import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.LinkedBlockingQueue;

import com.v1.video.R;
import com.v1.video.util.Utils;

import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

public class DanmuView extends LinearLayout {
	private Context mContext;
	private int mScreenWidth;
	private DanmuViewBaseAdapter baseAdapter;
	// 行数
	private int lineNum = 3;
	private boolean repeat = false;
	private Timer timer = new Timer();
	private Queue<Runnable> mQueue = new LinkedBlockingQueue<Runnable>();
	private List<Runnable> cacheQueue = new ArrayList<Runnable>();

	private int measureHeight = 0;
	private boolean isPause = false;

	public DanmuView(Context context) {
		super(context);
		setOrientation(LinearLayout.VERTICAL);
		mContext = context;
		mScreenWidth = Utils.getScreenWidth(context);
		initView();
	}

	public DanmuView(Context context, AttributeSet attrs) {
		super(context, attrs);
		setOrientation(LinearLayout.VERTICAL);
		mContext = context;
		mScreenWidth = Utils.getScreenWidth(context);
		TypedArray a = context.obtainStyledAttributes(attrs,
				R.styleable.DanmuView);
		repeat = a.getBoolean(R.styleable.DanmuView_repeat, false);
		a.recycle();
		initView();
	}

	private void initView() {
		for (int i = 0; i < lineNum; i++) {
			RelativeLayout relativeLayout = new RelativeLayout(mContext);
			LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
					LinearLayout.LayoutParams.MATCH_PARENT,
					LinearLayout.LayoutParams.WRAP_CONTENT);
			relativeLayout.setLayoutParams(params);
			this.addView(relativeLayout, i);
		}
	}

	/**
	 * 只能调用一次
	 * 
	 * @param adapter
	 */
	public void setAdapter(DanmuViewBaseAdapter adapter) {
		baseAdapter = adapter;
		startScroll();
	}

	public void notifyDatasetChange() {
		this.post(new Runnable() {

			@Override
			public void run() {
				initQueue();
			}
		});
	}

	private void initQueue() {
		if (baseAdapter == null) {
			return;
		}
		final int count = baseAdapter.getCount();
		for (int i = 0; i < count; i++) {
			int atIndex = i % 3;
			RelativeLayout child = (RelativeLayout) getChildAt(atIndex);
			if (i >= cacheQueue.size()) {
				DanmuEngine engine = new DanmuEngine(mContext, child, i);
				mQueue.add(engine);
				cacheQueue.add(engine);
			}
		}

		if (count <= 0) {
			cacheQueue.clear();
			mQueue.clear();
		} else {// 初次布局
			if (measureHeight == 0) {
				View itemView = baseAdapter.getView(0, null);
				itemView.measure(0, 0);
				measureHeight = itemView.getMeasuredHeight();
				for (int i = 0; i < lineNum; i++) {
					RelativeLayout child = (RelativeLayout) getChildAt(i);
					LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
							LinearLayout.LayoutParams.MATCH_PARENT,
							measureHeight);
					child.setLayoutParams(params);
					child.requestLayout();
				}
			}
		}
	}

	private void startScroll() {
		initQueue();
		timer.schedule(task, 1000, 1000);
	}

	TimerTask task = new TimerTask() {

		@Override
		public void run() {
			if (baseAdapter != null && !isPause) {
				DanmuEngine engine = (DanmuEngine) mQueue.poll();
				if (engine != null) {
					if (engine.getItemView() == null) {
						View itemView = baseAdapter.getView(
								engine.getIndexOfQueue(), null);
						engine.setItemView(itemView);
					}

					Message msg = handler.obtainMessage();
					msg.obj = engine;
					handler.sendMessage(msg);
				} else {
					if (repeat) {
						mQueue.addAll(cacheQueue);
					}
				}
			}
		}
	};

	private Handler handler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			super.handleMessage(msg);
			DanmuEngine engine = (DanmuEngine) msg.obj;
			if (!engine.isRunning()) {
				engine.run();
			}
		}

	};

	public void release() {
		timer.cancel();
		timer.purge();
	}

	public boolean isRepeat() {
		return repeat;
	}

	public void setRepeat(boolean repeat) {
		this.repeat = repeat;
	}

	public boolean isPlaying() {
		return !isPause;
	}

	public void pause() {
		this.isPause = true;
		this.setVisibility(View.INVISIBLE);
	}

	public void resume() {
		this.isPause = false;
		this.setVisibility(View.VISIBLE);
	}
}
